/**
 * 手势性能监控Hook
 * Story 5: Task 9 - 性能优化和测试
 */

import { useRef, useCallback } from 'react'

interface GesturePerformanceMetrics {
  responseTime: number // 手势响应时间（ms）
  frameRate: number // 动画帧率
  jankCount: number // 卡顿次数
}

interface PerformanceEntry {
  name: string
  startTime: number
  endTime?: number
  metrics?: GesturePerformanceMetrics
}

/**
 * 手势性能监控Hook
 * 监控手势响应时间、动画帧率等性能指标
 */
export const useGesturePerformance = () => {
  const entriesRef = useRef<Map<string, PerformanceEntry>>(new Map())
  const frameTimesRef = useRef<number[]>([])
  const animationFrameRef = useRef<number>()

  /**
   * 开始性能测量
   */
  const startMeasure = useCallback((name: string) => {
    const entry: PerformanceEntry = {
      name,
      startTime: performance.now(),
    }
    entriesRef.current.set(name, entry)

    // 开始帧率监控
    frameTimesRef.current = []
    const measureFrameRate = () => {
      frameTimesRef.current.push(performance.now())
      animationFrameRef.current = requestAnimationFrame(measureFrameRate)
    }
    measureFrameRate()
  }, [])

  /**
   * 结束性能测量
   */
  const endMeasure = useCallback((name: string) => {
    const entry = entriesRef.current.get(name)
    if (!entry) return null

    const endTime = performance.now()
    const responseTime = endTime - entry.startTime

    // 停止帧率监控
    if (animationFrameRef.current) {
      cancelAnimationFrame(animationFrameRef.current)
    }

    // 计算帧率和卡顿
    const frameTimes = frameTimesRef.current
    let frameRate = 0
    let jankCount = 0

    if (frameTimes.length > 1) {
      const totalTime = frameTimes[frameTimes.length - 1] - frameTimes[0]
      frameRate = Math.round((frameTimes.length / totalTime) * 1000)

      // 检测卡顿（帧时间 > 16.67ms = 60fps）
      for (let i = 1; i < frameTimes.length; i++) {
        const frameTime = frameTimes[i] - frameTimes[i - 1]
        if (frameTime > 16.67 * 2) {
          // 超过两帧的时间
          jankCount++
        }
      }
    }

    const metrics: GesturePerformanceMetrics = {
      responseTime,
      frameRate,
      jankCount,
    }

    entry.endTime = endTime
    entry.metrics = metrics

    // 在开发环境下输出性能警告
    if (process.env.NODE_ENV === 'development') {
      if (responseTime > 100) {
        console.warn(
          `[Gesture Performance] ${name} response time is too slow: ${responseTime.toFixed(2)}ms (target: <100ms)`
        )
      }

      if (frameRate < 60) {
        console.warn(
          `[Gesture Performance] ${name} frame rate is too low: ${frameRate}fps (target: 60fps)`
        )
      }

      if (jankCount > 0) {
        console.warn(
          `[Gesture Performance] ${name} detected ${jankCount} janks (frame drops)`
        )
      }
    }

    return metrics
  }, [])

  /**
   * 获取所有性能条目
   */
  const getEntries = useCallback(() => {
    return Array.from(entriesRef.current.values())
  }, [])

  /**
   * 清空性能数据
   */
  const clearEntries = useCallback(() => {
    entriesRef.current.clear()
    frameTimesRef.current = []
  }, [])

  /**
   * 生成性能报告
   */
  const generateReport = useCallback(() => {
    const entries = Array.from(entriesRef.current.values())
    const completedEntries = entries.filter((e) => e.metrics)

    if (completedEntries.length === 0) {
      return {
        totalGestures: 0,
        averageResponseTime: 0,
        averageFrameRate: 0,
        totalJanks: 0,
        performanceScore: 100,
      }
    }

    const totalGestures = completedEntries.length
    const avgResponseTime =
      completedEntries.reduce((sum, e) => sum + (e.metrics?.responseTime || 0), 0) /
      totalGestures
    const avgFrameRate =
      completedEntries.reduce((sum, e) => sum + (e.metrics?.frameRate || 0), 0) /
      totalGestures
    const totalJanks = completedEntries.reduce(
      (sum, e) => sum + (e.metrics?.jankCount || 0),
      0
    )

    // 计算性能得分（0-100）
    let score = 100
    if (avgResponseTime > 100) score -= 30
    else if (avgResponseTime > 50) score -= 15

    if (avgFrameRate < 60) score -= 20
    else if (avgFrameRate < 55) score -= 10

    if (totalJanks > 5) score -= 20
    else if (totalJanks > 2) score -= 10

    return {
      totalGestures,
      averageResponseTime: Math.round(avgResponseTime * 100) / 100,
      averageFrameRate: Math.round(avgFrameRate),
      totalJanks,
      performanceScore: Math.max(0, score),
    }
  }, [])

  return {
    startMeasure,
    endMeasure,
    getEntries,
    clearEntries,
    generateReport,
  }
}

/**
 * 性能测量装饰器
 * 用于包装手势处理函数
 */
export const withPerformanceMeasure = <T extends (...args: any[]) => any>(
  fn: T,
  gestureName: string
): T => {
  return ((...args: any[]) => {
    const startTime = performance.now()

    const result = fn(...args)

    const endTime = performance.now()
    const duration = endTime - startTime

    if (process.env.NODE_ENV === 'development' && duration > 100) {
      console.warn(
        `[Gesture Performance] ${gestureName} handler took ${duration.toFixed(2)}ms (target: <100ms)`
      )
    }

    return result
  }) as T
}
